home *** CD-ROM | disk | FTP | other *** search
/ Mac Format 1995 June / MacFormat 25.iso / Shareware City / Developers / OutOfPhase1.1 Source / OutOfPhase Folder / SampleTestPlay.c < prev    next >
Text File  |  1994-08-23  |  10KB  |  365 lines

  1. /* SampleTestPlay.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "SampleTestPlay.h"
  31. #include "SoundOutput.h"
  32. #include "Memory.h"
  33. #include "SampleWindow.h"
  34. #include "SampleConsts.h"
  35. #include "FixedPoint.h"
  36.  
  37. #define FRAMESPERBUFFER (8192)
  38. #define MAXBUFFERS (3)
  39. #define INITIALBUFFERS (MAXBUFFERS)
  40.  
  41. #define SIXTEENBITSHIFTFACTOR (10)
  42. #define EIGHTBITSHIFTFACTOR (18)
  43.  
  44.  
  45. typedef enum
  46.     {
  47.         eNoPlay EXECUTE(= -18481),
  48.         eLoopPlay,
  49.         eNoLoopPlay,
  50.         eWaiting
  51.     } InternalStates;
  52.  
  53. static InternalStates            State = eNoPlay;
  54.  
  55. static SampleTestErrors        ErrorOccurred;
  56. static SampleWindowRec*        Window;
  57. static largefixedsigned*    Data;
  58. static long                                LoopStart;
  59. static long                                LoopEnd;
  60. static long                                CurrentIndex;
  61. static NumBitsType                NumBits;
  62. static NumChannelsType        NumChannels;
  63. static long                                EndOfChannel;
  64. static MyBoolean                    DoingLoop;
  65.  
  66.  
  67. MyBoolean                    SampleTestPlayInProgress(void)
  68.     {
  69.         return State != eNoPlay;
  70.     }
  71.  
  72.  
  73. void                            SampleTestPlayCallback(SampleWindowRec* TheWindow, MyBoolean IgnoreMe)
  74.     {
  75.         void*                            Buffer;
  76.         long                            Scan;
  77.         long                            LocalIndex;
  78.         long                            LocalEnd;
  79.         largefixedsigned*    LocalData;
  80.         long                            Limit;
  81.  
  82.         if (State == eNoPlay)
  83.             {
  84.                 SoundOutputStereo        StereoRequest;
  85.                 SoundOutputNumBits    BitsRequest;
  86.  
  87.                 State = eLoopPlay;
  88.                 ErrorOccurred = eSampleTestNoError;
  89.  
  90.                 Window = TheWindow;
  91.  
  92.                 Data = SampleWindowGetRawFixedPointData(TheWindow);
  93.                 if (Data == NIL)
  94.                     {
  95.                         ErrorOccurred = eSampleTestNoSample;
  96.                         return;
  97.                     }
  98.                 SampleWindowFinalizeCurrentEdit(TheWindow);
  99.                 LoopStart = SampleWindowGetLoopStart(TheWindow);
  100.                 LoopEnd = SampleWindowGetLoopEnd(TheWindow);
  101.                 if (LoopEnd == LoopStart)
  102.                     {
  103.                         State = eNoLoopPlay;
  104.                     }
  105.                 CurrentIndex = 0;
  106.                 NumBits = SampleWindowGetNumBits(TheWindow);
  107.                 NumChannels = SampleWindowGetNumChannels(TheWindow);
  108.                 if (NumChannels == eSampleStereo)
  109.                     {
  110.                         StereoRequest = eStereo;
  111.                     }
  112.                  else
  113.                     {
  114.                         StereoRequest = eMono;
  115.                     }
  116.                 if (NumBits == eSample16bit)
  117.                     {
  118.                         BitsRequest = e16bit;
  119.                     }
  120.                  else
  121.                     {
  122.                         BitsRequest = e8bit;
  123.                     }
  124.                 if (!OpenSoundChannel(SampleWindowGetSamplingRate(TheWindow),
  125.                     StereoRequest,BitsRequest,FRAMESPERBUFFER,MAXBUFFERS,INITIALBUFFERS))
  126.                     {
  127.                         ErrorOccurred = eSampleTestCouldntOpenChannel;
  128.                         return;
  129.                     }
  130.                 DoingLoop = True;
  131.                 EndOfChannel = PtrSize((char*)Data) / sizeof(largefixedsigned);
  132.                 if (NumChannels == eSampleStereo)
  133.                     {
  134.                         EndOfChannel = EndOfChannel / 2;
  135.                     }
  136.             }
  137.  
  138.         if (State == eWaiting)
  139.             {
  140.                 return;
  141.             }
  142.         if (ErrorOccurred != eSampleTestNoError)
  143.             {
  144.                 return;
  145.             }
  146.         ERROR(Window != TheWindow,PRERR(ForceAbort,
  147.             "SampleTestPlayCallback:  window pointers are different"));
  148.  
  149.         /* set up local variable values */
  150.         Buffer = CheckOutSoundBuffer();
  151.         if (Buffer == NIL)
  152.             {
  153.                 return;
  154.             }
  155.         Scan = 0;
  156.         LocalIndex = CurrentIndex;
  157.         LocalData = Data;
  158.         Limit = FRAMESPERBUFFER;
  159.  
  160.         /* use one of the 8 synthesis techniques */
  161.         if (State == eNoLoopPlay)
  162.             {
  163.                 LocalEnd = EndOfChannel; /* for no loop, the end is the real end */
  164.                 if (NumChannels == eSampleStereo)
  165.                     {
  166.                         if (NumBits == eSample16bit)
  167.                             {
  168.                                 /* stereo, 16-bit, no loop */
  169.                                 PRNGCHK(Buffer,Buffer,sizeof(short) * Limit * 2);
  170.                                 while (Scan < Limit)
  171.                                     {
  172.                                         if (LocalIndex >= LocalEnd)
  173.                                             {
  174.                                                 goto AllDonePoint;
  175.                                             }
  176.                                         ((signed short*)Buffer)[Scan * 2 + 0]
  177.                                             = LocalData[LocalIndex * 2 + 0] >> SIXTEENBITSHIFTFACTOR;
  178.                                         ((signed short*)Buffer)[Scan * 2 + 1]
  179.                                             = LocalData[LocalIndex * 2 + 1] >> SIXTEENBITSHIFTFACTOR;
  180.                                         LocalIndex += 1;
  181.                                         Scan += 1;
  182.                                     }
  183.                             }
  184.                          else
  185.                             {
  186.                                 /* stereo, 8-bit, no loop */
  187.                                 PRNGCHK(Buffer,Buffer,sizeof(char) * Limit * 2);
  188.                                 while (Scan < Limit)
  189.                                     {
  190.                                         if (LocalIndex >= LocalEnd)
  191.                                             {
  192.                                                 goto AllDonePoint;
  193.                                             }
  194.                                         ((signed char*)Buffer)[Scan * 2 + 0]
  195.                                             = LocalData[LocalIndex * 2 + 0] >> EIGHTBITSHIFTFACTOR;
  196.                                         ((signed char*)Buffer)[Scan * 2 + 1]
  197.                                             = LocalData[LocalIndex * 2 + 1] >> EIGHTBITSHIFTFACTOR;
  198.                                         LocalIndex += 1;
  199.                                         Scan += 1;
  200.                                     }
  201.                             }
  202.                     }
  203.                  else
  204.                     {
  205.                         if (NumBits == eSample16bit)
  206.                             {
  207.                                 /* mono, 16-bit, no loop */
  208.                                 PRNGCHK(Buffer,Buffer,sizeof(short) * Limit);
  209.                                 while (Scan < Limit)
  210.                                     {
  211.                                         if (LocalIndex >= LocalEnd)
  212.                                             {
  213.                                                 goto AllDonePoint;
  214.                                             }
  215.                                         ((signed short*)Buffer)[Scan]
  216.                                             = LocalData[LocalIndex] >> SIXTEENBITSHIFTFACTOR;
  217.                                         LocalIndex += 1;
  218.                                         Scan += 1;
  219.                                     }
  220.                             }
  221.                          else
  222.                             {
  223.                                 /* mono, 8-bit, no loop */
  224.                                 PRNGCHK(Buffer,Buffer,sizeof(char) * Limit);
  225.                                 while (Scan < Limit)
  226.                                     {
  227.                                         if (LocalIndex >= LocalEnd)
  228.                                             {
  229.                                                 goto AllDonePoint;
  230.                                             }
  231.                                         ((signed char*)Buffer)[Scan]
  232.                                             = LocalData[LocalIndex] >> EIGHTBITSHIFTFACTOR;
  233.                                         LocalIndex += 1;
  234.                                         Scan += 1;
  235.                                     }
  236.                             }
  237.                     }
  238.                 goto SubmitPoint;
  239.                 /* skip this */
  240.              AllDonePoint:
  241.                 /* end of channel, time to stop playing */
  242.                 SubmitBuffer((char*)Buffer,Scan,NIL,NIL);
  243.                 State = eWaiting;
  244.                 return;
  245.             }
  246.          else
  247.             {
  248.                 LocalEnd = LoopEnd; /* for loop, this is what the end is */
  249.                 if (NumChannels == eSampleStereo)
  250.                     {
  251.                         if (NumBits == eSample16bit)
  252.                             {
  253.                                 /* stereo, 16-bit, yes loop */
  254.                                 PRNGCHK(Buffer,Buffer,sizeof(short) * Limit * 2);
  255.                                 while (Scan < Limit)
  256.                                     {
  257.                                         if (LocalIndex == LocalEnd)
  258.                                             {
  259.                                                 LocalIndex = LoopStart;
  260.                                             }
  261.                                         ((signed short*)Buffer)[Scan * 2 + 0]
  262.                                             = LocalData[LocalIndex * 2 + 0] >> SIXTEENBITSHIFTFACTOR;
  263.                                         ((signed short*)Buffer)[Scan * 2 + 1]
  264.                                             = LocalData[LocalIndex * 2 + 1] >> SIXTEENBITSHIFTFACTOR;
  265.                                         LocalIndex += 1;
  266.                                         Scan += 1;
  267.                                     }
  268.                             }
  269.                          else
  270.                             {
  271.                                 /* stereo, 8-bit, yes loop */
  272.                                 PRNGCHK(Buffer,Buffer,sizeof(char) * Limit * 2);
  273.                                 while (Scan < Limit)
  274.                                     {
  275.                                         if (LocalIndex == LocalEnd)
  276.                                             {
  277.                                                 LocalIndex = LoopStart;
  278.                                             }
  279.                                         ((signed char*)Buffer)[Scan * 2 + 0]
  280.                                             = LocalData[LocalIndex * 2 + 0] >> EIGHTBITSHIFTFACTOR;
  281.                                         ((signed char*)Buffer)[Scan * 2 + 1]
  282.                                             = LocalData[LocalIndex * 2 + 1] >> EIGHTBITSHIFTFACTOR;
  283.                                         LocalIndex += 1;
  284.                                         Scan += 1;
  285.                                     }
  286.                             }
  287.                     }
  288.                  else
  289.                     {
  290.                         if (NumBits == eSample16bit)
  291.                             {
  292.                                 /* mono, 16-bit, yes loop */
  293.                                 PRNGCHK(Buffer,Buffer,sizeof(short) * Limit);
  294.                                 while (Scan < Limit)
  295.                                     {
  296.                                         if (LocalIndex == LocalEnd)
  297.                                             {
  298.                                                 LocalIndex = LoopStart;
  299.                                             }
  300.                                         ((signed short*)Buffer)[Scan]
  301.                                             = LocalData[LocalIndex] >> SIXTEENBITSHIFTFACTOR;
  302.                                         LocalIndex += 1;
  303.                                         Scan += 1;
  304.                                     }
  305.                             }
  306.                          else
  307.                             {
  308.                                 /* mono, 8-bit, yes loop */
  309.                                 PRNGCHK(Buffer,Buffer,sizeof(char) * Limit);
  310.                                 while (Scan < Limit)
  311.                                     {
  312.                                         if (LocalIndex == LocalEnd)
  313.                                             {
  314.                                                 LocalIndex = LoopStart;
  315.                                             }
  316.                                         ((signed char*)Buffer)[Scan]
  317.                                             = LocalData[LocalIndex] >> EIGHTBITSHIFTFACTOR;
  318.                                         LocalIndex += 1;
  319.                                         Scan += 1;
  320.                                     }
  321.                             }
  322.                     }
  323.             }
  324.  
  325.         /* play the data and write changed values out */
  326.      SubmitPoint:
  327.         SubmitBuffer((char*)Buffer,Limit,NIL,NIL);
  328.         CurrentIndex = LocalIndex;
  329.     }
  330.  
  331.  
  332. void                            SampleTestBreakLoop(void)
  333.     {
  334.         ERROR(State != eLoopPlay,PRERR(ForceAbort,
  335.             "SampleTestBreakLoop:  cancelling loop but it isn't looping"));
  336.         State = eNoLoopPlay;
  337.     }
  338.  
  339.  
  340. SampleTestErrors    SampleTestDidErrorOccur(void)
  341.     {
  342.         return ErrorOccurred;
  343.     }
  344.  
  345.  
  346. void                            SampleTestPlayCleanup(void)
  347.     {
  348.         ERROR(State == eNoPlay,PRERR(ForceAbort,
  349.             "SampleTestPlayCleanup:  nothing is playing"));
  350.         CloseSoundChannel(NIL,NIL);
  351.         State = eNoPlay;
  352.     }
  353.  
  354.  
  355. MyBoolean                    SampleTestIsItLooping(void)
  356.     {
  357.         return State == eLoopPlay;
  358.     }
  359.  
  360.  
  361. MyBoolean                    SampleTestIsWaitingForCleanup(void)
  362.     {
  363.         return State == eWaiting;
  364.     }
  365.